<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用公共文件


//curl提交
function curl($url, $post = false, $postData = []) {
    $ch = curl_init(); //初始化一个CURL对象
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    if ($post) {
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
    }
    $data = curl_exec($ch);
    curl_close($ch);
    return $data;
}

//获取客户端IP
function get_client_ip($type = 0) {
    $type = $type ? 1 : 0;
    static $ip = NULL;
    if ($ip !== NULL) return $ip[$type];
    if (isset($_SERVER['HTTP_X_REAL_IP'])) {//nginx 代理模式下，获取客户端真实IP
        $ip = $_SERVER['HTTP_X_REAL_IP'];
    } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {//客户端的ip
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {//浏览当前页面的用户计算机的网关
        $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        $pos = array_search('unknown', $arr);
        if (false !== $pos) unset($arr[$pos]);
        $ip = trim($arr[0]);
    } elseif (isset($_SERVER['REMOTE_ADDR'])) {
        $ip = $_SERVER['REMOTE_ADDR'];//浏览当前页面的用户计算机的ip地址
    } else {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    // IP地址合法验证
    $long = sprintf("%u", ip2long($ip));
    $ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
    return $ip[$type];
}

//验证用户IP是否允许访问
function user_ip_allow() {
    $con_loginreg_ip = config('con_loginreg_ip');
    if ($con_loginreg_ip) {
        $client_ip = get_client_ip();
        $shield_ip_arr = explode(',', $con_loginreg_ip);
        if (in_array($client_ip, $shield_ip_arr)) {
            return false;
        }
    }
    return true;
}

function SetCookies($data = []) {
    $_session_id = md5($data['cookie_id']);
    if (isset($data['cookie_status']) && $data['cookie_status'] == 1) {
        if ($data["time"] != "") {
            setcookie("wd_cookie_time", $data["time"], time() + $data["time"], "/", null, null, TRUE);
            $_ctime = time() + $data["time"];
        } else {
            $_ctime = time() + $_COOKIE["wd_cookie_time"];
            setcookie("wd_cookie_time", $_COOKIE["wd_cookie_time"], $_ctime, "/", null, null, TRUE);
        }
        setcookie($_session_id, authcode($data['user_id'] . "," . time(), "ENCODE"), $_ctime, "/", null, null, TRUE);
    } else {
        if ($data["time"] != "") {
            session('wd_cookie_time', $data["time"]);
        }
        session($_session_id, authcode($data['user_id'] . "," . time(), "ENCODE"));
        session('login_endtime', time() + $data["time"]);
    }
}

function GetCookies($data = []) {
    $_session_id = md5($data['cookie_id']);
    if (isset($data['cookie_status']) && $data['cookie_status'] == 1) {
        $_user_id = explode(",", authcode(isset($_COOKIE[$_session_id]) ? $_COOKIE[$_session_id] : "", "DECODE"));
    } else {
        $_user_id = explode(",", authcode(session($_session_id) ? session($_session_id) : "", "DECODE"));
    }
    return $_user_id[0];
}

/**
 * 清除cookie
 * @param $param array('session_id' => '缓存ID')
 * @return Null
 */
function DelCookies($data = []) {
    $_session_id = md5($data['cookie_id']);
    setcookie($_session_id, "", time() - 3600);
    session($_session_id, null);
    session('login_endtime', null);
}

/**
 * 3,加密程序
 */
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
    // 动态密匙长度，相同的明文会生成不同密文就是依靠动态密匙
    $ckey_length = 4;
    // 密匙
    $key = md5($key ? $key : "dw10c20m05w18");
    // 密匙a会参与加解密
    $keya = md5(substr($key, 0, 16));
    // 密匙b会用来做数据完整性验证
    $keyb = md5(substr($key, 16, 16));
    // 密匙c用于变化生成的密文
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';
    // 参与运算的密匙
    $cryptkey = $keya . md5($keya . $keyc);
    $key_length = strlen($cryptkey);
    // 明文，前10位用来保存时间戳，解密时验证数据有效性，10到26位用来保存$keyb(密匙b)，解密时会通过这个密匙验证数据完整性
    // 如果是解码的话，会从第$ckey_length位开始，因为密文前$ckey_length位保存 动态密匙，以保证解密正确
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
    $string_length = strlen($string);
    $result = '';
    $box = range(0, 255);
    $rndkey = array();

    // 产生密匙簿
    for ($i = 0; $i <= 255; $i++) {
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
    }

    // 用固定的算法，打乱密匙簿，增加随机性，好像很复杂，实际上对并不会增加密文的强度
    for ($j = $i = 0; $i < 256; $i++) {
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp = $box[$i];
        $box[$i] = $box[$j];
        $box[$j] = $tmp;
    }

    // 核心加解密部分
    for ($a = $j = $i = 0; $i < $string_length; $i++) {
        $a = ($a + 1) % 256;
        $j = ($j + $box[$a]) % 256;
        $tmp = $box[$a];
        $box[$a] = $box[$j];
        $box[$j] = $tmp;
        // 从密匙簿得出密匙进行异或，再转成字符
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    }


    if ($operation == 'DECODE') {
        // substr($result, 0, 10) == 0 验证数据有效性
        // substr($result, 0, 10) - time() > 0 验证数据有效性
        // substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16) 验证数据完整性
        // 验证数据有效性，请看未加密明文的格式
        if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
            return substr($result, 26);
        } else {
            return '';
        }
    } else {
        // 把动态密匙保存在密文里，这也是为什么同样的明文，生产不同密文后能解密的原因
        // 因为加密后的密文可能是一些特殊字符，复制过程可能会丢失，所以用base64编码
        return $keyc . str_replace('=', '', base64_encode($result));
    }
}

function isLogin() {
    return GetCookies([
            'cookie_status' => config('con_cache_type'),
            'cookie_id' => config('con_cookie_id'),
    ]);
}

function isPhone($phone) {
    return preg_match('/^1\d{10}$/', $phone) ? true : false;
}

function IsChinese($str) {
    return preg_match("/^[\x{4e00}-\x{9fa5}]+$/u", $str) ? true : false;
}

function isIdCard($number) {
    //加权因子
    $wi = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
    //校验码串
    $ai = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
    //按顺序循环处理前17位
    $sigma = 0;
    for ($i = 0; $i < 17; $i++) {
        //提取前17位的其中一位，并将变量类型转为实数
        $b = (int) $number{$i};

        //提取相应的加权因子
        $w = $wi[$i];

        //把从身份证号码中提取的一位数字和加权因子相乘，并累加
        $sigma += $b * $w;
    }
    //计算序号
    $snumber = $sigma % 11;

    //按照序号从校验码串中提取相应的字符。
    $check_number = $ai[$snumber];

    if ($number{17} == $check_number) {
        return true;
    } else {
        return false;
    }
}

function get_sex($id_number) {
    $strlen = strlen($id_number);
    if ($strlen == 18) {
        $number = substr($id_number, -2, 1);
    } elseif ($strlen == 15) {
        $number = substr($id_number, -1, 1);
    } else {
        return 0;
    }
    return $number % 2 ? 1 : 2;
}

function IsExiest($val) {
    if (isset($val) && ($val != "" || $val == 0)) {
        return $val;
    } else {
        return false;
    }
}

//隐藏手机中间四位
function hideMobile($phone) {
    if (!$phone) {
        return null;
    }
    return substr($phone, 0, 3) . '****' . substr($phone, -4);
}

function get_times($data = array()) {

    if (isset($data['time']) && $data['time'] != "") {
        $time = $data['time'];//时间
    } elseif (isset($data['date']) && $data['date'] != "") {
        $time = strtotime($data['date']);//日期
    } else {
        $time = time();//现在时间
    }
    if (isset($data['type']) && $data['type'] != "") {
        $type = $data['type'];//时间转换类型，有day week month year
    } else {
        $type = "month";
    }
    if (isset($data['num']) && ($data['num'] != "" || $data['num'] == "0")) {
        $num = $data['num'];
    } else {
        $num = 1;
    }
    if ($type == "month") {
        $month = date("m", $time);
        $year = date("Y", $time);
        $_result = strtotime("$num month", $time);
        $_month = (int) date("m", $_result);
        if ($month + $num > 12) {
            $_num = $month + $num - 12;
            $year = $year + 1;
        } else {
            $_num = $month + $num;
        }

        if ($_num != $_month) {

            //$_result = strtotime("-1 day",strtotime("{$year}-{$_month}-01"));
        }
    } else {
        $_result = strtotime("$num $type", $time);
    }
    if (isset($data['format']) && $data['format'] != "") {
        return date($data['format'], $_result);
    } else {
        return $_result;
    }
}

//获取时间
function get_mktime($mktime) {
    if ($mktime == "") return "";
    $dtime = trim(preg_replace("/[ ]{1,}/", " ", $mktime));
    $ds = explode(" ", $dtime);
    $ymd = explode("-", $ds[0]);
    if (isset($ds[1]) && $ds[1] != "") {
        $hms = explode(":", $ds[1]);
        $mt = mktime(empty($hms[0]) ? 0 : $hms[0], !isset($hms[1]) ? 0 : $hms[1], !isset($hms[2]) ? 0 : $hms[2], !isset($ymd[1]) ? 0 : $ymd[1], !isset($ymd[2]) ? 0 : $ymd[2], !isset($ymd[0]) ? 0 : $ymd[0]);
    } else {
        $mt = mktime(0, 0, 0, !isset($ymd[1]) ? 0 : $ymd[1], !isset($ymd[2]) ? 0 : $ymd[2], !isset($ymd[0]) ? 0 : $ymd[0]);
    }
    return $mt;
}

function array_sort($arr, $keys, $type = 'desc') {
    $keysvalue = $new_array = array();
    foreach ($arr as $k => $v) {
        $keysvalue[$k] = $v[$keys];
    }
    if ($type == 'asc') {
        asort($keysvalue);
    } else {
        arsort($keysvalue);
    }
    reset($keysvalue);
    foreach ($keysvalue as $k => $v) {
        $new_array[] = $arr[$k];
    }
    return $new_array;
}


/**
 * 通用接口发短信
 * apikey 为云片分配的apikey
 * text 为短信内容
 * mobile 为接受短信的手机号
 */
function send_sms($apikey, $text, $mobile){
    $url="http://yunpian.com/v1/sms/send.json";
    $encoded_text = urlencode("$text");
    $post_string="apikey=$apikey&text=$encoded_text&mobile=$mobile";
    return sock_post($url, $post_string);
}

/**
 * 模板接口发短信
 * apikey 为云片分配的apikey
 * tpl_id 为模板id
 * tpl_value 为模板值
 * mobile 为接受短信的手机号
 */
function tpl_send_sms($apikey, $tpl_id, $tpl_value, $mobile){
    $url="http://yunpian.com/v1/sms/tpl_send.json";
    $encoded_tpl_value = urlencode("$tpl_value");  //tpl_value需整体转义
    $post_string="apikey=$apikey&tpl_id=$tpl_id&tpl_value=$encoded_tpl_value&mobile=$mobile";
    return sock_post($url, $post_string);
}

/**
 * url 为服务的url地址
 * query 为请求串
 */
function sock_post($url,$query){
    $data = "";
    $info=parse_url($url);
    $fp=fsockopen($info["host"],80,$errno,$errstr,30);
    if(!$fp){
        return $data;
    }
    $head="POST ".$info['path']." HTTP/1.0\r\n";
    $head.="Host: ".$info['host']."\r\n";
    $head.="Referer: http://".$info['host'].$info['path']."\r\n";
    $head.="Content-type: application/x-www-form-urlencoded\r\n";
    $head.="Content-Length: ".strlen(trim($query))."\r\n";
    $head.="\r\n";
    $head.=trim($query);
    $write=fputs($fp,$head);
    $header = "";
    while ($str = trim(fgets($fp,4096))) {
        $header.=$str;
    }
    while (!feof($fp)) {
        $data .= fgets($fp,4096);
    }
    return $data;
}